{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img src=\"images/strathsdr_banner.png\" align=\"left\">"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Hardware Accelerated Spectrum Analysis on RFSoC\n",
    "----\n",
    "\n",
    "<div class=\"alert alert-box alert-info\">\n",
    "Please use Jupyter Labs http://board_ip_address/lab for this notebook.\n",
    "</div>\n",
    "\n",
    "This notebook presents a flexible hardware accelerated Spectrum Analyzer Module for the Zynq UltraScale+ RFSoC. The Spectrum Analyzer Module was developed by the [University of Strathclyde](https://github.com/strath-sdr).\n",
    "\n",
    "## Table of Contents\n",
    "* [Introduction](#introduction)\n",
    "    * [Hardware Setup](#hardware-setup)\n",
    "    * [Software Setup](#software-setup)\n",
    "* [Simple Tone Generation](#simple-tone-generation)\n",
    "* [The Spectrum Analyzer](#the-spectrum-analyzer)\n",
    "    * [A Simple Example](#a-simple-example)\n",
    "* [Conclusion](#conclusion)\n",
    "    \n",
    "## References\n",
    "* [Xilinx, Inc, \"USP RF Data Converter: LogiCORE IP Product Guide\", PG269, v2.3, June 2020](https://www.xilinx.com/support/documentation/ip_documentation/usp_rf_data_converter/v2_3/pg269-rf-data-converter.pdf)\n",
    "\n",
    "## Revision History\n",
    "* **v1.0** | 12/02/2021 | Spectrum analyzer notebook\n",
    "* **v1.1** | 15/04/2021 | Update spectral resolution and minimum bandwidth with new value"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "----"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Introduction <a class=\"anchor\" id=\"introduction\"></a>\n",
    "The Zynq RFSoC contains high frequency samplers known as RF Data Converters (RF DCs). The RF DCs are tightly coupled with the Programmable Logic (PL), creating a high-throughput, low-latency path between the FPGA and analogue world. The Spectrum Analyzer Module employs the RF Analogue-to-Digital Converters (RF ADCs) to receive RF time domain signals. The received data is manipulated using spectral pre-processing techniques in the PL, to prepare it for frequency domain analysis and visualisation in the Processing System (PS).\n",
    "\n",
    "A significant portion of the design has been implemented in the RFSoC's PL to prevent the PS from applying highly computational arithemtic. [Figure 1](#fig-1) presents a simple diagram illustrating the system overview for one spectrum analyzer channel. There is a Spectrum Analyzer Module for each available RF ADC channel in the design. The Spectrum Analyzers are also interfaced to their very own flexible decimator, allowing different sample rates to be configured for each channel."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a class=\"anchor\" id=\"fig-1\"></a>\n",
    "<figure>\n",
    "<img src='images/spectrum_analyser_overview.png' height='50%' width='50%'/>\n",
    "    <figcaption><b>Figure 1: The RFSoC Spectrum Analyzer system overview.</b></figcaption>\n",
    "</figure>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Hardware Setup <a class=\"anchor\" id=\"hardware-setup\"></a>\n",
    "Your ZCU111 development board can host four Spectrum Analyzer Modules. To setup your board for this demonstration, you can connect each channel in loopback as shown in [Figure 2](#fig-2), or connect an antenna to one of the ADC channels.\n",
    "\n",
    "Don't worry if you don't have an antenna. The default loopback configuration will still be very interesting and is connected as follows:\n",
    "* Channel 0: DAC4 (Tile 229 Block 0) to ADC0 (Tile 224 Block 0)\n",
    "* Channel 1: DAC5 (Tile 229 Block 1) to ADC1 (Tile 224 Block 1)\n",
    "* Channel 2: DAC6 (Tile 229 Block 2) to ADC2 (Tile 225 Block 0)\n",
    "* Channel 3: DAC7 (Tile 229 Block 3) to ADC3 (Tile 225 Block 1)\n",
    "\n",
    "There has been several XM500 board revisions, and some contain different silkscreen and labels for the ADCs and DACs. Use the image below for further guidance and pay attention to the associated Tile and Block.\n",
    "\n",
    "<a class=\"anchor\" id=\"fig-2\"></a>\n",
    "<figure>\n",
    "<img src='images/zcu111_setup.png' height='50%' width='50%'/>\n",
    "    <figcaption><b>Figure 2: ZCU111 and XM500 development board setup in loopback mode.</b></figcaption>\n",
    "</figure>\n",
    "\n",
    "If you have chosen to use an antenna, **do not** attach your antenna to any SMA interfaces labelled DAC.\n",
    "\n",
    "<div class=\"alert alert-box alert-danger\">\n",
    "<b>Caution:</b>\n",
    "    In this demonstration, we generate tones using the RFSoC development board. Your device should be setup in loopback mode. You should understand that the RFSoC platform can also transmit RF signals wirelessly. Remember that unlicensed wireless transmission of RF signals may be illegal in your geographical location. Radio signals may also interfere with nearby devices, such as pacemakers and emergency radio equipment. Note that it is also illegal to intercept and decode particular RF signals. If you are unsure, please seek professional support.\n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Software Setup <a class=\"anchor\" id=\"software-setup\"></a>\n",
    "We're nearly finished setting up the demonstration system. The majority of the libraries used by the spectrum analyzer design are contained inside the RFSoC-SAM software package. We only need to run a few code cells to initialise the software environment.\n",
    "\n",
    "The primary module for loading the Spectrum Analyzer design is contained inside `rfsoc_sam.overlay`. The class we are interested in using is `Overlay()`. During initialisation the class downloads the Spectrum Analyzer bitstream to the PL and configures the RF DCs and FPGA IP cores contained in our system. This process may take around a minute to complete.\n",
    "\n",
    "**Run** the code cell below to load the RFSoC-SAM Overlay class."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from rfsoc_sam.overlay import Overlay\n",
    "\n",
    "sam = Overlay()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "When the RFSoC-SAM Overlay class is initialising, the setup script will also program the LMK and LMX low-jitter clock chips on the ZCU111 to 122.8MHz and 409.6MHz respectively.\n",
    "\n",
    "Lets now initialise the analyzer, and setup user control. The initialisation process takes around 2 minutes."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "analyzer = sam.spectrum_analyzer()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "----"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Simple Tone Generation <a class=\"anchor\" id=\"simple-tone-generation\"></a>\n",
    "A simple amplitude controller is required to generate tones using the RF Digital-to-Analogue Converters (RF DACs). We use tone generation in this demonstration to provide a signal for the user to inspect when using the Spectrum Analyzer Module.\n",
    "\n",
    "Run the code cell below to reveal a widget, which can be used to control the transmission frequency and amplitude."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "analyzer.children[2]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## The Spectrum Analyzer <a class=\"anchor\" id=\"the-spectrum-analyzer\"></a>\n",
    "We will now explore the hardware accelerated Spectrum Analyzer Module. It is worthwhile noting the analyzers capabilities below:\n",
    "\n",
    "* The analyzer is capable of inspecting 1638.4MHz of bandwidth.\n",
    "* It can achieve a maximum spectral resolution of 0.244140625kHz. \n",
    "* The bandwidth is adjustable between 1638.4MHz and 1.6MHz.\n",
    "* The range of inspection is between 0 to 4096MHz using higher order Nyquist techniques."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "analyzer.children[1]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The Spectrum Analyzer Module contains a hardware accelerated FFT core, which can convert the RF sampled signal to the frequency domain using a range of different FFT lengths, $N = 64$ upto $N = 8192$. The frequency domain signal is further manipulated using a custom floating point processor to obtain the representative Power Spectral Density (PSD) or Power Spectrum. Furthermore, a hardware accelerated decibel (dB) converter is also used to condition the frequency domain signal for visual analysis.\n",
    "\n",
    "Through the loopback connection, you should be able to use the Spectrum Analyzer Module to locate the tone you previously generated using the tone generator. If you have an antenna connected to your board, try and locate signals of interest using the Spectrum Analyzer's control widgets."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### A Simple Example <a class=\"anchor\" id=\"a-simple-example\"></a>\n",
    "If you would like to enable stimulus for the spectrum analyzer, you can use your mobile phone to create WiFi traffic. Follow the steps below to create an interesting WiFi spectrum to visualise.\n",
    "* Connect your mobile phone to an access point that uses WiFi. \n",
    "* Then configure the spectrum analyzer for a centre frequency of 2400MHz and a decimation factor of 16. \n",
    "* Switch on the spectrum analyzer and spectrogram.\n",
    "* Use your phone to stream a video, or music. This will create WiFi traffic for inspection.\n",
    "* Place your phone close to the RF ADC ports of the spectrum analyzer.\n",
    "\n",
    "You should see a similar output as given in the [Figure 3](#fig-3) below.\n",
    "\n",
    "<a class=\"anchor\" id=\"fig-3\"></a>\n",
    "<figure>\n",
    "<img src='images/wifi_example.jpg' height='50%' width='50%'/>\n",
    "    <figcaption><b>Figure 3: Capturing a WiFi signal using the Spectrum Analyser Module.</b></figcaption>\n",
    "</figure>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Conclusion <a class=\"anchor\" id=\"conclusion\"></a>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This notebook has presented a hardware accelerated Spectrum Analyzer Module for the ZCU111 development board."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  },
  "widgets": {
   "application/vnd.jupyter.widget-state+json": {
    "state": {},
    "version_major": 2,
    "version_minor": 0
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}